﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Windows.Forms;

#region Using
using HJ212_Protocol;
using HJT212_Protocol_DAL.DAO;
using HJT212_Protocol_DAL.Model;
using SailHero.Soft.ESB.Collections;
using SailHero.Soft.ESB.Communication.ClientAndServer.Communication.EndPoints.Tcp;
using SailHero.Soft.ESB.Communication.ClientAndServer.Communication.Messages;
using SailHero.Soft.ESB.Communication.ClientAndServer.Server;
#endregion

namespace HJT212_Protocol_Server
{
    public partial class ServerMainForm : Form
    {
        #region 构造函数
        public ServerMainForm()
        {
            InitializeComponent();
        }
        #endregion

        #region 字段属性
        private IServer server;
        private List<ClientModel> LstClients = new List<ClientModel>();
        public static List<HostClientModel> LstHostClients = new List<HostClientModel>();
        #endregion

        #region 事件

        private void btnSrvStart_Click(object sender, EventArgs e)
        {
            try
            {
                string _port = ConfigurationManager.AppSettings["SrvPort"];
                server = ServerFactory.CreateServer(new ESBTcpEndPoint(Convert.ToInt32(_port)));
                server.WireProtocolFactory = new MyWireProtocolFactory(); //自定义通讯协议工厂!
                server.ClientConnected += server_ClientConnected;
                server.ClientDisconnected += server_ClientDisconnected;
                server.Start();
                string msg = "服务已启动.\r\n";
                ShowMsg(msg, 2);
                this.btnSrvStart.Enabled = false;
            }
            catch (Exception ex)
            {

                throw;
            }

        }

        private void server_ClientDisconnected(object sender, ServerClientEventArgs e)
        {
            Delegate ddd = new Action(ShowOnlineClients);
            this.BeginInvoke(ddd);
        }

        private void btnSrvStop_Click(object sender, EventArgs e)
        {
            try
            {
                if (server != null)
                {
                    server.Stop();
                    this.btnSrvStart.Enabled = true;
                }
            }
            catch (Exception ex)
            {

                throw;
            }
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            UpdateOffLineAll();
            Process.GetCurrentProcess().Kill();
        }

        private void server_ClientConnected(object sender, ServerClientEventArgs e)
        {
            string msg = "客户机已建立连接.地址 : " + e.Client.RemoteEndPoint + "\r\n";
            ShowMsg(msg, 2);
            e.Client.MessageReceived += Client_MessageReceived;
            e.Client.ClientLogin += Client_ClientLogin;
        }

        private void Client_ClientLogin(object sender, MessageEventArgs e)
        {
            IServerClient srvclient = (IServerClient)(sender);
            OnLogin(srvclient, e.Message);
        }

        private void Client_MessageReceived(object sender, MessageEventArgs e)
        {
            try
            {
                IServerClient srvclnt = (IServerClient)sender;
                ParameterizedThreadStart Start = new ParameterizedThreadStart(o => MsgReceived(srvclnt, e.Message));
                Thread Thrd = new Thread(Start);
                Thrd.Start();
            }
            catch (Exception ex)
            {

                throw;
            }

        }


        private void ServerMainForm_Load(object sender, EventArgs e)
        {
            try
            {
                Delegate ddd = new Action(showDBClients);
                this.BeginInvoke(ddd);
            }
            catch (Exception EX)
            {

                throw;
            }
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
            UpdateOffLineAll();
            Process.GetCurrentProcess().Kill();
        }

        private void OnLogin(IServerClient srvClient, IMessage msg)
        {
            ShowClients(srvClient, msg);
            //SendClntsToHostClnt(server.Clients);
        }

        #endregion

        #region 方法函数

        private void UpdateOffLineAll()
        {
            try
            {
                foreach (ClientModel mdl in LstClients)
                {
                    ClientDao dao = new ClientDao();
                    dao.UpdateOnlineState(mdl.MN, 0);
                }
                foreach (HostClientModel mdl in LstHostClients)
                {
                    HostClientDao dao = new HostClientDao();
                    dao.UpdateOnlineState(mdl.MN, 0);
                }
            }
            catch (Exception ex)
            {
                
                throw;
            }
        }

        private void MsgReceived(IServerClient clent, IMessage Msg)
        {
            try
            {
                try
                {
                    TextMessage Tmsg = (TextMessage)Msg;
                    int MSGType = 1;//等于0时是从上位机请求，等于1时是从现场机返回
                    #region 记录
                    string fromMN = clent.MN;
                    string toMN = Tmsg.MN;
                    //判断MN是否以XHHB起始，如果是，说明是我司上位机
                    if (!string.IsNullOrEmpty(fromMN) && fromMN.StartsWith("XHHB"))
                    {
                        MSGType = 0;
                        MsgCacheDao cacheDao = new MsgCacheDao();
                        cacheDao.InsertToCache(Tmsg.Text, fromMN);
                    }
                    #endregion

                    #region 转发
                    if (MSGType == 0)
                    {
                        var lstSClients = server.Clients.GetAllItems().Where(
                            delegate(IServerClient itm)
                            {
                                return itm.MN == toMN;
                            });

                        if (lstSClients != null && lstSClients.Count() > 0)
                        {
                            IServerClient itm = lstSClients.First();
                            itm.SendMessage(Tmsg);
                        }
                    }
                    else if (MSGType == 1)
                    {
                        MsgCacheDao dao = new MsgCacheDao();
                        string CMN = dao.FindMNByQNFromCache(Tmsg.QN);
                        if (!string.IsNullOrEmpty(CMN))
                        {
                            var lstSClients = server.Clients.GetAllItems().Where(
                                delegate(IServerClient itm)
                                {
                                    return itm.MN.Trim() == CMN;
                                });
                            if (lstSClients != null && lstSClients.Count() > 0)
                            {
                                IServerClient itm = lstSClients.First();
                                itm.SendMessage(Tmsg);
                            }
                        }
                    }

                    #endregion

                }
                catch (Exception ex)
                {

                    throw;
                }

            }
            catch (Exception ex)
            {

                throw;
            }
        }
        /// <summary>
        /// 显示客户端列表数据至列表控件
        /// </summary>
        /// <param name="clients">客户端列表</param>
        private void ShowClients(IServerClient srvClient, IMessage msg)
        {

            try
            {
                Delegate ddd = new
                    Action<IMessage>(
                    delegate(IMessage message)
                    {

                        //this.lstBoxClients.Items.Clear();
                        if (srvClient == null) return;
                        TextMessage Tmsg = (TextMessage)message;
                        if (message == null || server.Clients.Count <= 0)
                        {
                            return;
                        }

                        if (string.IsNullOrEmpty(Tmsg.MN) || string.IsNullOrEmpty(Tmsg.PW))
                        {
                            //非法客户端，强制踢出
                            srvClient.Disconnect();
                            string mesg = @"客户端：" + Tmsg.MN.Trim() + ",为非法客户端，已强制让其退出\r\n";
                            ShowMsg(mesg, 1);
                            return;
                        }
                        if (LstClients == null || LstClients.Count <= 0)
                        {
                            // InitConn();
                            ClientDao dao = new ClientDao();
                            LstClients = dao.GetDbClientList();
                        }
                        if (LstHostClients == null || LstHostClients.Count <= 0)
                        {
                            // InitConn();
                            HostClientDao dao = new HostClientDao();
                            LstHostClients = dao.GetDbClientList();
                        }
                        var hostclnts = LstHostClients.Where(itm => itm.MN == Tmsg.MN && itm.PW == Tmsg.PW);
                        if (hostclnts == null || hostclnts.Count() <= 0)
                        {
                            var clnts = LstClients.Where(itm => itm.MN == Tmsg.MN && itm.PW == Tmsg.PW);
                            if (clnts == null || clnts.Count() <= 0)
                            {
                                //非法客户端，强制踢出
                                srvClient.Disconnect();
                                return;
                            }
                        }

                        ShowOnlineClients();

                    });
                this.BeginInvoke(ddd, msg);
            }
            catch (Exception ex)
            {

                throw;
            }
        }
        /// <summary>
        /// 显示所有在线的客户端
        /// </summary>
        private void ShowOnlineClients()
        {
            try
            {
                List<IServerClient> List = server.Clients.GetAllItems();
                LstClients.ForEach(itm => itm.OnLineState = 0);
                LstHostClients.ForEach(itm => itm.OnLineState = 0);
                List<ListViewItem> lst = lstBoxClients.Items.Cast<ListViewItem>().ToList();
                lst.ForEach(
                    delegate(ListViewItem itm)
                    {
                        itm.Font =
                            new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular,
                                                    System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                        itm.ForeColor = Color.Black;
                    });


                foreach (IServerClient scsServerClient in List)
                {
                    

                    var source = LstClients.Where(itm => itm.MN == scsServerClient.MN);

                    if (source != null && source.Count() > 0)
                    {
                        source.First().OnLineState = 1;
                        var lvs = lstBoxClients.Items.Cast<ListViewItem>().ToList().Where(itm => itm.SubItems[1].Text == scsServerClient.MN);
                        if (lvs == null || lvs.Count() <= 0) return;
                        ListViewItem lvtm = lvs.First();
                        lvtm.Font = new Font("宋体", 9, FontStyle.Bold);
                        lvtm.ForeColor = Color.LightGreen;
                    }
                    else
                    {
                        var source1 = LstHostClients.Where(itm => itm.MN == scsServerClient.MN);
                        if (source1 != null && source1.Count() > 0)
                        {
                            source1.First().OnLineState = 1;
                        }
                    }

                }
               
                foreach (ClientModel mdl in LstClients)
                {
                    ClientDao dao = new ClientDao();
                    dao.UpdateOnlineState(mdl.MN, mdl.OnLineState);
                }
                foreach (HostClientModel mdl in LstHostClients)
                {
                    HostClientDao dao = new HostClientDao();
                    dao.UpdateOnlineState(mdl.MN, mdl.OnLineState);
                }

            }
            catch (Exception ex)
            {

                throw;
            }
        }
        /// <summary>
        /// 以不同状态显示数据
        /// </summary>
        /// <param name="msg">显示的数据</param>
        /// <param name="type">状态表示，2 黑色 否则红色</param>
        private void ShowMsg(string msg, int type)
        {
            Delegate ddd = new Action<string>(delegate(string str)
            {
                this.txtBoxContent.AppendText(str);
                txtBoxContent.Select(Math.Max(0, this.txtBoxContent.Text.Length - str.Length), str.Length);
                txtBoxContent.SelectionColor = type == 2 ? Color.Black : Color.Red;
                txtBoxContent.ScrollToCaret();
            });
            this.BeginInvoke(ddd, msg);
        }


        /// <summary>
        /// 加载数据库中配置的客户端列表
        /// </summary>
        private void showDBClients()
        {
            try
            {
                lstBoxClients.Items.Clear();
                ClientDao dao = new ClientDao();
                LstClients = dao.GetDbClientList();
                if (LstClients != null && LstClients.Count > 0)
                {
                    foreach (ClientModel mdl in LstClients)
                    {
                        lstBoxClients.Items.Add(new ListViewItem(new[]
                                                                     {
                                                                         mdl.MCNName,
                                                                         mdl.MN,
                                                                         mdl.PW,
                                                                         "1"
                                                                     }));
                    }
                }
            }
            catch (Exception ex)
            {

                throw;
            }
        }


        #endregion

    }
}
